﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Configuration;
using GoToTags.Nfc;
using GoToTags.Nfc.Ndef;
using GoToTags.Nfc.Reader;
using GoToTags.Nfc.Records;
using GoToTags.Nfc.Util;
using GoToTags.Nfc.Models;
using Touch2Like.Tags;
using System.Web;
using System.Net;
using System.IO;

namespace Touch2Like.Samples
{
    public partial class Form1 : Form
    {
        private static string TagUID = "";
        static NfcAdapter nfcAdapter;

        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
            comboBox_Selection.SelectedIndex = 0;
            Licensing.Unlock(Utility.LicenseKey);
            try
            {
                var isCertPropSvcRunning = CertPropSvc.IsRunning();
                if (isCertPropSvcRunning)
                {
                    MessageBox.Show("The CertPropSvc Service is running; it interferes with NFC and should be stopped.");
                    CertPropSvc.StopService();
                }
                //else
                //{
                //    MessageBox.Show("The CertPropSvc service is not running.");
                //}
            }
            catch (Exception)
            {
                // trap exceptions here, some systems dont have this service
            }

            Record.RegisterRecordType(new RecordType("GitHub", "GitHub", typeof(GitHubRecord), 2, GitHubRecord.ToGitHubRecord));
            // get all the record types that have been registered
            var recordTypes = Record.GetRecordTypes();

            nfcAdapter = NfcAdapter.DefaultAdapter;
            if (nfcAdapter == null)
            {

                MessageBox.Show("No NFC readers found");

            }

            //bool scanSerialPorts = false;
            //MessageBox.Show(string.Format("Supported NFC readers (scanSerialPorts = {0}):", scanSerialPorts));
            var readers = NfcAdapter.SupportedReaders(false);
            if (readers.Count() != 0)
            {
                comboBox_Reader.DataSource = readers;
                label_Status.Text = "Reader is connected";
            }
            else
                label_Status.Text = "No Reader Found";

            // use the first reader
            if (comboBox_Reader.Items.Count != 0)
            {
                var reader = comboBox_Reader.SelectedItem.ToString();
                NfcAdapter.Adapter(reader);
                nfcAdapter.StatusChanged += nfcAdapter_StatusChanged;
            }
        }

        private void LinkLabel_Touch2Like_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            Process proc = new Process();
            proc.EnableRaisingEvents = false;
            proc.StartInfo.FileName = "http://www.camintelgroup.com";
            proc.Start();
        }

        private void checkBox_MarkItReadOnly_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_MarkItReadOnly.Checked)
                MessageBox.Show("WARNING!! By checking this, you will not be able to write back to the tag.","Warning");
            
        }

        private void button_Exit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void checkBox_Touch2LIke_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_Touch2LIke.Checked)
            {
                if (string.IsNullOrEmpty(TagUID))
                {
                    MessageBox.Show("Please place the tag on the card reader!", "Warning");
                    checkBox_Touch2LIke.Checked = false;
                }
                else
                {
                    string url = ConfigurationManager.AppSettings["Server"].ToString();
                    if (url.EndsWith("/"))
                        url = url.Remove(url.Length - 1, 1);
                    textBox_Url.Text = url + "/touch.aspx?tag=" + TagUID;
                    textBox_Url.ReadOnly = true;
                }
            }
        }

        private void button_Clear_Click(object sender, EventArgs e)
        {
            label_IsFormatted.Text = "";
            label_IsReadOnly.Text = "";
            label_IsWritable.Text = "";
            label_TagUID.Text = "";
            label_TagType.Text = "";
            checkBox_MarkItReadOnly.Checked = false;
            checkBox_Touch2LIke.Checked = false;
            label_Warning.Text = "";
            textBox_Url.Text = "";
            textBox_Read.Text = "";
            TagUID = "";
            MessageBox.Show("All fields have been reset!", "Touch2Like");
           
        }

        private void button_Erase_Click(object sender, EventArgs e)
        {
            DialogResult result = MessageBox.Show("By clicking the Erase button, it will erase the content in the NFC Tag. Are you sure you want to proceed?", "Warning", MessageBoxButtons.YesNo);
            if (result == DialogResult.Yes)
            {
                var reader = comboBox_Reader.SelectedItem.ToString();
                NfcAdapter.Adapter(reader);
                // get the tag
                try
                {
                    var tag = nfcAdapter.GetTag();
                    using (var ndef = NdefTechnology.Get(tag))
                    {

                        ndef.Connect();

                        var isWritable = ndef.IsWritable;

                        if (isWritable)
                        {
                            ndef.Erase();
                            MessageBox.Show("The contents in the tag have been erased.");
                        }
                        else
                            MessageBox.Show("The tag cannot be erased.");
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else
                return;
        
        }

        private void nfcAdapter_StatusChanged(object sender, StatusChangedEventArgs args)
        {
            var tag = nfcAdapter.GetTag();
            if (tag != null)
            {
                using (var ndef = NdefTechnology.Get(tag))
                {
                    ndef.Connect();
                    var records = ndef.GetRecords();
                    var tagUID = ndef.TagUIDString();

                    label_IsFormatted.Text = ndef.IsFormatted.ToString();
                    label_TagUID.Text = ndef.TagUIDString();
                    TagUID = ndef.TagUIDString();
                    label_IsReadOnly.Text = ndef.CanMakeReadOnly.ToString();
                    label_IsWritable.Text = ndef.IsWritable.ToString();
                    label_TagType.Text = tag.TagType.ToString();

                    if (records.Length == 0)
                        textBox_Read.Text = "No content found in the tag";
                    else
                    {
                        foreach (var record in records)
                        {
                            try
                            {
                                SendData(BuildString(tagUID, record.ToString()));
                            }
                            catch { }
                            finally
                            {
                                //MessageBox.Show(string.Format("{0}: {1}", record.RecordType, record));
                                if (record is WebsiteRecord)
                                {
                                    textBox_Read.Text = record.ToString();
                                    //Process proc = new Process();
                                    //proc.EnableRaisingEvents = false;
                                    //proc.StartInfo.FileName = record.ToString();
                                    //proc.Start();
                                }
                                else if (record is EmailRecord)
                                {
                                    // blah
                                }
                                else if (record is TextRecord)
                                {

                                }
                            }
                        }
                    }
                }
            }
            else
            {
                label_IsFormatted.Text = "";
                label_TagUID.Text = "";
                label_IsReadOnly.Text = "";
                label_IsWritable.Text = "";
                label_TagType.Text = "";
                textBox_Read.Text = "";
                TagUID = "";

            }
        }

        private void SendData(string dataString)
        {
            byte[] postBytes = Encoding.ASCII.GetBytes(dataString);

            string url = ConfigurationManager.AppSettings["Server"].ToString();
            if (url.EndsWith("/"))
                url = url.Remove(url.Length - 1, 1);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + "/Validate.aspx");
            request.Headers.Add("SOAPActon", "\"\"");
            request.ContentType = "text/xml;charset=\"utf-8\"";
            request.Accept = "text/xml";
            request.Method = "POST";
            //request.ContentLength = postBytes.Length;
            string base64EncodedAuthorizationString = Utility.WCFUsername + ":" + Utility.WCFPassword;
            byte[] binaryData = new Byte[base64EncodedAuthorizationString.Length];
            binaryData = Encoding.UTF8.GetBytes(base64EncodedAuthorizationString);
            base64EncodedAuthorizationString = Convert.ToBase64String(binaryData);
            base64EncodedAuthorizationString = "Basic " + base64EncodedAuthorizationString;
            request.Headers.Set("Authorization", base64EncodedAuthorizationString);


            Stream stream = request.GetRequestStream();
            stream.Write(postBytes, 0, postBytes.Length);
            stream.Close();

            WebResponse response = request.GetResponse();
            stream = response.GetResponseStream();

        }

        private static string BuildString(string tagUID, string content)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<Touch2Like>");
            sb.Append("<TagUID>" + tagUID + "</TagUID>");
            sb.Append("<Content>" + content + "</Content>");
            sb.Append("</Touch2Like>");
            return sb.ToString();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var reader = comboBox_Reader.SelectedItem.ToString();
            NfcAdapter.Adapter(reader);
            // get the tag
            var tag = nfcAdapter.GetTag();
            if (tag == null)
            {
                MessageBox.Show("An NFC tag is not on the reader.");
            }
            else
            {
                var tagTech = tag.TagType;
                //MessageBox.Show(string.Format("Tag Tech: {0}", tagTech));
                // ndef operations
                using (var ndef = NdefTechnology.Get(tag))
                {
                    ndef.Connect();
                    var isWritable = ndef.IsWritable;
                    if (isWritable)
                    {
                        ndef.Erase();
                        var websiteRecord = new TextRecord();
                        websiteRecord.Text = textBox_Url.Text.ToString();
                        MessageBox.Show("Data is updated in the tag");
                        ndef.WriteNdefMessage(websiteRecord);

                        if ( checkBox_MarkItReadOnly.Checked)
                            ndef.MakeReadOnly();
                    }
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                SendData(BuildString("Touch2LikeTest", "Touch2LikeTest"));
            }
            catch (Exception Exception)
            {
                MessageBox.Show(Exception.Message);
            }
        }

    }
}
